;Copyright 2007-2010 Niko Carpenter and Tyler Spivey
;    This file is part of Linna Home Server.
;    Linna Home is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;    any later version.

;    Linna Home is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with Linna Home.  If not, see http://www.gnu.org/licenses/.

#include-once
Func SRVLIB_Init()
Global enum $C_Sock, $C_Buffer
Global $SRVLIBAU_AR[1][2]
$srvlibAU_ar[0][$C_Sock] = -1
EndFunc
Func SRVLib_Recv($close,$Sock,$count)
local $ar = -1
$Return = ""
for $i = 0 to ubound($SRVLibAU_Ar)-1
if $Sock = $SRVLibAU_Ar[$i][$c_sock] Then
$ar = $i
ExitLoop
EndIf
Next
if $ar = -1 Then Return
$SRVLibAU_Ar[$ar][$C_Buffer] &= TCPRecv($Sock,$Count)
if @Error Then
SRVLib_CloseConnection($close,$Ar)
	EndIf
$SRVLibAU_Ar[$ar][$C_Buffer] = StringReplace($SRVLibAU_Ar[$ar][$C_Buffer],@CRLF,@LF)
$SRVLibAU_Ar[$ar][$C_Buffer] = StringReplace($SRVLibAU_Ar[$ar][$C_Buffer],@CR,@LF)
if StringInStr($SRVLibAU_Ar[$ar][$C_Buffer],@lf) Then
$return =StringLeft($SRVLibAU_Ar[$ar][$C_Buffer],StringInStr($SRVLibAU_Ar[$ar][$C_Buffer],@lf)-1)
$SRVLibAU_Ar[$ar][$C_Buffer] = StringTrimLeft($SRVLibAU_Ar[$Ar][$C_Buffer],StringInStr($SRVLibAU_Ar[$ar][$C_Buffer],@lf))
if $return = "" Then $return = @lf
return $return
EndIf
EndFunc

Func SRVLib_Send($Lid,$msg)
if $LID < 0 or $LID > UBound($SRVLibAU_Ar)-1 Then return
$msg &= @LF
$linz = StringSplit($msg,@LF)
if not @Error Then
For $i = 1 to $linz[0]
if $linz[$i] <> "" Then
TCPSend($SRVLibAU_Ar[$lid][$C_Sock],$linz[$i]&@CRLF)
EndIf
Next
EndIf
EndFunc
Func SRVLib_DoConnectionCheck($Connection,$Init)
if $Connection >= 0 Then
local $ac = -1
$ac = TCPAccept($Connection)
if $ac >= 0 Then
local $found = -1
for $i = 0 to UBound($SRVLibAU_Ar)-1
if $SRVLibAU_Ar[$i][$C_Sock] = -1 Then
$Found = $i
ExitLoop
EndIf
Next
if $Found = -1 Then
Redim $SRVLibAU_Ar[UBound($SRVLibAU_Ar)+1][UBound($SRVLibAU_Ar,2)]
$Found = uBound($SRVLibAU_Ar)-1
EndIf
$SRVLibAu_Ar[$found][$C_Buffer] = ""
$SRVLibAu_Ar[$found][$C_Sock] = $ac
if not Call($Init,$Found,$ac) Then
TCPCloseSocket($SRVLibAu_Ar[$found][$C_Sock])
$SRVLibAu_Ar[$Found][$C_Sock] = -1
EndIf
EndIf
EndIf
EndFunc
Func SRVLib_CloseConnection($Func,$ID)
TCPCloseSocket($SRVLibAU_Ar[$Id][$C_Sock])
$SRVLibAU_Ar[$id][$C_Sock] = -1
Call($Func,$ID)
EndFunc
Func SRVLib_DoRecv($Close,$Func)
for $i = 0 to UBound($SRVLibAU_Ar)-1
if $SRVLibAU_Ar[$i][$C_Sock] >= 0 Then
$Recv = SRVLib_Recv($close,$SRVLibAU_Ar[$i][$C_Sock],1024)
if $recv <> "" Then
Call($Func,$i,$Recv)
EndIf
EndIf
Next
EndFunc
Func SRVLib_DoServerEvents($Connection,$Init,$close,$recvfunc)
SRVLib_DoConnectionCheck($Connection,$Init)
SRVLib_DoRecv($Close,$RecvFunc)
EndFunc
Func SRVLib_SendAll($MSG, $SplitHorizonID = -1)
for $i = 0 to uBound($SRVLibAU_Ar)-1
if not $SplitHorizonID = $i and SRVLib_GetSock($i) >= 0 Then SRVLib_Send($i,$MSG)
Next
EndFunc

Func SRVLib_SocketToIP($SHOCKET)
    Local $sockaddr = DLLStructCreate("short;ushort;uint;char[8]")

    Local $aRet = DLLCall("Ws2_32.dll","int","getpeername","int",$SHOCKET, _
            "ptr",DLLStructGetPtr($sockaddr),"int*",DLLStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
        $aRet = DLLCall("Ws2_32.dll","str","inet_ntoa","int",DLLStructGetData($sockaddr,3))
        If Not @error Then $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf

    $sockaddr = 0

    Return $aRet
EndFunc
Func SRVLib_GetSock($id)
if StringIsInt($id) = 0 or $id <= -1 or $id > uBound($SRVLibAu_Ar)-1 Then Return -1
return $SRVLibAu_Ar[$id][$C_Sock]
EndFunc

Func SRVLib_ShutDown()
for $i = 0 to uBound($SRVLibAU_Ar)-1
if SRVLib_GetSock($i) >= 0 Then TCPCloseSocket(SRVLib_GetSock($i))
Next
TCPShutDown()
EndFunc
